﻿using CommunicationLib.Enums;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PlcLib.Model
{
    /// <summary>
    /// 下发数据的指令
    /// </summary>
    public struct Command
    {
        public OperatorMode OperatorMode { get; private set; }
        public AreaType AreaType { get; private set; }
        public DataType DataType { get; private set; }
        public int Length { get; private set; }
        public int WordAddress { get; private set; }
        public byte BitAddress { get; private set; }
        public Command(
            OperatorMode operatorMode,
            AreaType areaType,
            DataType dataType,
            int length,
            int wordAddress,
            byte bitAddress = 0)
        {
            OperatorMode = operatorMode;
            AreaType = areaType;
            DataType = dataType;
            Length = length;
            WordAddress = wordAddress;
            BitAddress = bitAddress;
        }

        /// <summary>
        /// 区域
        /// </summary>
        public byte Area
        {
            get
            {
                byte area = 0;
                switch (AreaType)
                {
                    case AreaType.AR:
                        area = DataType == DataType.Bit ? (byte)0x33 : (byte)0xB3;
                        break;
                    case AreaType.HR:
                        area = DataType == DataType.Bit ? (byte)0x32 : (byte)0xB2;
                        break;
                    case AreaType.WR:
                        area = DataType == DataType.Bit ? (byte)0x31 : (byte)0xB1;
                        break;
                    case AreaType.CIO:
                        area = DataType == DataType.Bit ? (byte)0x30 : (byte)0xB0;
                        break;
                    case AreaType.DM:
                        area = DataType == DataType.Bit ? (byte)0x02 : (byte)0x82;
                        break;
                }

                return area;
            }
        }

        public byte[] GetReadBuffer(Net net, long commandNumber)
        {
            if (OperatorMode != OperatorMode.Read)
            {
                throw new Exception("读取PLC时OperatorMode模式应为Read");
            }

            int dataByteLength = 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//A
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] lengths = BitConverter.GetBytes(dataByteLength);
            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x02;

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;
            sendBuffer[22] = 0x00;
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读命令
            sendBuffer[27] = 0x01;//读命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            sendBuffer[32] = (byte)((Length >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(Length & 0xff);//长度低位

            return sendBuffer;
        }

        public byte[] GetWriteBuffer(Net net, long commandNumber, int data)
        {
            return GetWriteBuffer(net, commandNumber, new List<int> { data });
        }

        public byte[] GetWriteBuffer(Net net, long commandNumber, List<int> data)
        {
            if (OperatorMode != OperatorMode.Write)
            {
                throw new Exception("写入PLC时OperatorMode模式应为Write");
            }

            if (data == null || data.Count == 0)
            {
                throw new Exception("写入PLC时,写入值不能为空");
            }

            if (data.Count > 100)
            {
                throw new Exception("写入PLC时,集合元素不能超过100个");
            }

            ushort[] writeArray;//最终写入PLC的数组

            if (DataType == DataType.WordBCD)
            {
                if (data[0] < 0 || data[0] > 9999)
                {
                    throw new Exception("写入PLC时,WordBCD写入值不符合要求");
                }
                writeArray = new ushort[] { (ushort)data[0] };//BCD码只取第一个元素
                writeArray[0] = ushort.Parse(writeArray[0].ToString(), NumberStyles.AllowHexSpecifier);
            }
            else
            {
                //适配任意写入长度，以Length属性为准
                var array = data.ToArray();
                var tempArray = new ushort[array.Length * 2];

                for (int i = 0; i < array.Length; i++)
                {
                    tempArray[2 * i] = (ushort)(data[i] & 0xffff);//低位
                    tempArray[2 * i + 1] = (ushort)((data[i] >> 16) & 0xffff);//高位
                }

                writeArray = new ushort[Length * 2];
                if (tempArray.Length < writeArray.Length)
                {
                    throw new Exception("写入PLC时,写入实际数据的长度和预设长度不一致");
                }
                for (int i = 0; i < writeArray.Length; i++)
                {
                    writeArray[i] = tempArray[i];
                }
            }

            var dataArray = writeArray;//要写入的数据
            int dataByteLength = (DataType == DataType.Bit ? 1 : 2) * dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//A
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] lengths = BitConverter.GetBytes(dataByteLength);
            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x02;

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;
            sendBuffer[22] = 0x00;
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            if (DataType == DataType.Bit)
            {
                sendBuffer[34] = (byte)dataArray[0];
            }
            else
            {
                //将写入的数据附到byte[]后面
                for (int i = 0; i < dataArray.Length; i++)
                {
                    sendBuffer[34 + 2 * i] = (byte)((dataArray[i] >> 8) & 0xff);
                    sendBuffer[34 + 2 * i + 1] = (byte)(dataArray[i] & 0xff);
                }
            }

            return sendBuffer;
        }

        //以下是支持泛型的PLC数据写入转换方法

        //private Net net;
        //private long commandNumber;

        public byte[] GetWriteBuffer<T>(Net net, long commandNumber, T data)
        {
            if (DataType == DataType.Bit && (BitAddress < 0 || BitAddress > 15))
            {
                throw new Exception("位地址超出0-15范围");
            }
            byte[] result = new byte[0];

            Type type = typeof(T);

            switch (type.FullName)
            {
                //单个变量
                case "System.Boolean":
                    result = GetBooleanBytes(net, commandNumber, (bool)(object)data);
                    break;
                case "System.Byte":
                    byte[] byteArray = new byte[] { (byte)(object)data };
                    result = GetByteBytes(net, commandNumber, byteArray);
                    break;
                case "System.Single":
                    float[] floatArray = new float[] { (float)(object)data };
                    result = GetSingleBytes(net, commandNumber, floatArray);
                    break;
                case "System.Int16":
                    short[] shortArray = new short[] { (short)(object)data };
                    result = GetInt16Bytes(net, commandNumber, shortArray);
                    break;
                case "System.UInt16":
                    ushort[] ushortArray = new ushort[] { (ushort)(object)data };
                    result = GetUInit16Bytes(net, commandNumber, ushortArray);
                    break;
                case "System.Int32":
                    int[] intArray = new int[] { (int)(object)data };
                    result = GetInt32Bytes(net, commandNumber, intArray);
                    break;
                case "System.UInt32":
                    uint[] uintArray = new uint[] { (uint)(object)data };
                    result = GetUInt32Bytes(net, commandNumber, uintArray);
                    break;

                //数组
                case "System.Byte[]":
                    result = GetByteBytes(net, commandNumber, (byte[])(object)data);
                    break;
                case "System.Single[]":
                    result = GetSingleBytes(net, commandNumber, (float[])(object)data);
                    break;
                case "System.Int16[]":
                    result = GetInt16Bytes(net, commandNumber, (short[])(object)data);
                    break;
                case "System.UInt16[]":
                    result = GetUInit16Bytes(net, commandNumber, (ushort[])(object)data);
                    break;
                case "System.Int32[]":
                    result = GetInt32Bytes(net, commandNumber, (int[])(object)data);
                    break;
                case "System.UInt32[]":
                    result = GetUInt32Bytes(net, commandNumber, (uint[])(object)data);
                    break;
            }

            return result;
        }

        //获取uint数组类型的下发指令
        private byte[] GetUInt32Bytes(Net net, long commandNumber, uint[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("uint数组不能为空");
            }

            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }

            //处理BCD码
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = uint.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }

            var source = new byte[data.Length * 4];  //int占4字节

            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);

                //高低位转换
                for (int j = 0; j < array.Length; j = j + 2)
                {
                    //(array[j], array[j + 1]) = (array[j + 1], array[j]);

                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }

                source[i * 4] = array[0];
                source[i * 4 + 1] = array[1];
                source[i * 4 + 2] = array[2];
                source[i * 4 + 3] = array[3];
            }

            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面
            int index = 0;
            for (int i = 34; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }

            return sendBuffer;
        }

        //获取int数组类型的下发指令
        private byte[] GetInt32Bytes(Net net, long commandNumber, int[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("int数组不能为空");
            }

            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }

            //处理BCD码
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = int.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }

            var source = new byte[data.Length * 4];  //int占4字节

            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);

                //高低位转换
                for (int j = 0; j < array.Length; j = j + 2)
                {
                    //(array[j], array[j + 1]) = (array[j + 1], array[j]);

                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }

                source[i * 4] = array[0];
                source[i * 4 + 1] = array[1];
                source[i * 4 + 2] = array[2];
                source[i * 4 + 3] = array[3];
            }

            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面
            int index = 0;
            for (int i = 34; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }

            return sendBuffer;
        }

        //获取ushort数组类型的下发指令
        private byte[] GetUInit16Bytes(Net net, long commandNumber, ushort[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("ushort数组不能为空");
            }

            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }

            //处理BCD码
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = ushort.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }

            var source = new byte[data.Length * 2];//ushort=2个字节
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);

                //高低位转换
                for (int j = 0; j < array.Length; j = j + 2)
                {
                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
                source[i * 2] = array[0];
                source[i * 2 + 1] = array[1];
            }

            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面
            int index = 0;
            for (int i = 34; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }

            return sendBuffer;
        }

        //获取short数组类型的下发指令
        private byte[] GetInt16Bytes(Net net, long commandNumber, short[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("short数组不能为空");
            }

            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }

            //处理BCD码
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = short.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }

            var source = new byte[data.Length * 2];//short=2个字节
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);

                //高低位转换
                for (int j = 0; j < array.Length; j = j + 2)
                {
                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
                source[i * 2] = array[0];
                source[i * 2 + 1] = array[1];
            }

            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面
            int index = 0;
            for (int i = 34; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }

            return sendBuffer;
        }

        //获取float数组类型的下发指令
        private byte[] GetSingleBytes(Net net, long commandNumber, float[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("float数组不能为空");
            }

            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }

            //处理BCD码
            if (DataType == DataType.WordBCD)
            {
                throw new Exception("暂不支持float写入BCD码");
            }

            var source = new byte[data.Length * 4];  //float占4字节

            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);

                //高低位转换
                for (int j = 0; j < array.Length; j = j + 2)
                {
                    //(array[j], array[j + 1]) = (array[j + 1], array[j]);

                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }

                source[i * 4] = array[0];
                source[i * 4 + 1] = array[1];
                source[i * 4 + 2] = array[2];
                source[i * 4 + 3] = array[3];
            }

            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面
            int index = 0;
            for (int i = 34; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }

            return sendBuffer;
        }

        //获取byte数组类型的下发指令
        private byte[] GetByteBytes(Net net, long commandNumber, byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("byte数组不能为空");
            }

            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }

            //处理BCD码
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = byte.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }

            var dataByteLength = data.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = data.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面
            int index = 0;
            for (int i = 34; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = data[index++];
            }

            return sendBuffer;

        }

        //获取bool数组类型的下发指令
        private byte[] GetBooleanBytes(Net net, long commandNumber, bool data)
        {
            var dataArray = new byte[] { (byte)(data ? 1 : 0) };
            var dataByteLength = dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46;//F
            sendBuffer[1] = 0x49;//I
            sendBuffer[2] = 0x4e;//N
            sendBuffer[3] = 0x53;//S

            //4位数据长度
            byte[] length = GetBytesLength(dataByteLength);
            sendBuffer[4] = length[0];
            sendBuffer[5] = length[1];
            sendBuffer[6] = length[2];
            sendBuffer[7] = length[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            sendBuffer[12] = 0x00;//错误码
            sendBuffer[13] = 0x00;//错误码
            sendBuffer[14] = 0x00;//错误码
            sendBuffer[15] = 0x00;//错误码

            sendBuffer[16] = 0x80;//ICF
            sendBuffer[17] = 0x00;//RSV
            sendBuffer[18] = 0x02;//GCT
            sendBuffer[19] = 0x00;//DNA

            sendBuffer[20] = net.ServerLastNode;//PLC地址最后一位
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x00;//SNA
            sendBuffer[23] = net.ClientLastNode;//电脑地址最后一位

            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandNumber;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写命令

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((WordAddress >> 8) & 0xFF); //字的地址
            sendBuffer[30] = (byte)(WordAddress & 0xff);//字的地址
            sendBuffer[31] = BitAddress;//位的地址 0-15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((count >> 8) & 0xFF); //长度高位
            sendBuffer[33] = (byte)(count & 0xff);//长度低位

            //将写入的数据附到byte[]后面

            sendBuffer[34] = dataArray[0];//写入数据


            return sendBuffer;
        }

        /// <summary>
        /// 获取下发指令数据长度字节数组
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private byte[] GetBytesLength(int value)
        {
            return BitConverter.GetBytes(value).Reverse().ToArray();//反转数组，高位在前，低位在后
        }
    }
}
